/*
 * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef IP_NETWORK_API_H_
#define IP_NETWORK_API_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "cmsis_os2.h"
typedef enum network_state_callback_event_t {
    NETWORK_UP,  /* The network is configured. */
    NETWORK_DOWN /* The network connection has been lost. */
} network_state_callback_event_t;

enum ip_address_family_t { IP_V4_ADDR = 4, IP_V6_ADDR = 6 };

typedef struct ip_address_t {
    /* NB: the "correct" type for this field is "enum ip_address_family_t",
     * however as the compiler can choose the underlying type for an enum we use
     * a fixed-width integer for consistency's sake.
     */
    uint8_t type;
    union {
        /* Stored in network byte order */
        uint32_t ipv4;
        uint32_t ipv6[4];
    } addr;
} ip_address_t;

typedef struct network_up_event_args_t {
    ip_address_t ip;
} network_up_event_args_t;

typedef struct network_down_event_args_t {
    /* NB: This is a "dummy" field used to ensure the struct is the same size
     * between C and C++. It also allows future extension of the type whilst
     * maintaining ABI compatibility.

     */
    uint8_t _;
} network_down_event_args_t;

typedef struct network_state_event_args_t {
    network_state_callback_event_t event;
    union {
        network_up_event_args_t up_event_args;
        network_down_event_args_t down_event_args;
    };
} network_state_event_args_t;

/**
 * User provided hook for network state change
 * @param event_args Tagged event arguments.
 */
typedef void (*network_state_callback_t)(const network_state_event_args_t *event_args);

/** Initialise and run the network stack.
 *
 * @param network_state_callback pointer to network_state_callback_t that will be called when network changes state.
 * @param stack_size stack size for the thread handling data, uses default stack size if set to 0.
 *
 * @return osOK if successful, osError if it couldn't be started.
 */
osStatus_t start_network_task(network_state_callback_t network_state_callback, uint32_t stack_size);

#ifdef __cplusplus
}
#endif

#endif // IP_NETWORK_API_H_
